package com.duoduo.动态规划;

/**
 * @program: algorithm
 * @description: 买卖股票的最佳时机121
 * 给定一个数组 prices ，它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
 *
 * 你只能选择 某一天 买入这只股票，并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
 *
 * 返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润，返回 0 。
 *
 *  
 *
 * 示例 1：
 *
 * 输入：[7,1,5,3,6,4]
 * 输出：5
 * 解释：在第 2 天（股票价格 = 1）的时候买入，在第 5 天（股票价格 = 6）的时候卖出，最大利润 = 6-1 = 5 。
 *      注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格；同时，你不能在买入前卖出股票。
 * 示例 2：
 *
 * 输入：prices = [7,6,4,3,1]
 * 输出：0
 * 解释：在这种情况下, 没有交易完成, 所以最大利润为 0。
 * @author: chaidl  ！
 * @create: 2022-05-05 22:56
 */
public class 买卖股票的最佳时机121 {
	public static void main(String[] args) {
		int i = new 买卖股票的最佳时机121().maxProfit3(new int[]{7, 1, 5, 3, 6, 4});
		System.out.println(i);
	}
	public int maxProfit3(int[] prices) {
		int length=prices.length;
		if(length==0){
			return 0;
		}
		int[] dp=new int[length];
		// 最小值就是第一个值
		int minPrices=prices[0];
		dp[0]=0;
		for(int i=1;i<length;i++){
			dp[i]=Math.max(dp[i-1],prices[i]-minPrices);
			minPrices=Math.min(minPrices,prices[i]);
		}
		return dp[length-1];
	}
	//动态规划
	public int maxProfit2(int[] prices) {
		int[] dp = new int[2];
		// 记录一次交易，一次交易有买入卖出两种状态
		// 0代表持有，1代表卖出
		dp[0] = -prices[0];
		dp[1] = 0;
		// 可以参考斐波那契问题的优化方式
		// 我们从 i=1 开始遍历数组，一共有 prices.length 天，
		// 所以是 i<=prices.length
		for (int i = 1; i <= prices.length; i++) {
			// 前一天持有；或当天买入
			dp[0] = Math.max(dp[0], -prices[i - 1]);
			// 如果 dp[0] 被更新，那么 dp[1] 肯定会被更新为正数的 dp[1]
			// 而不是 dp[0]+prices[i-1]==0 的0，
			// 所以这里使用会改变的dp[0]也是可以的
			// 当然 dp[1] 初始值为 0 ，被更新成 0 也没影响
			// 前一天卖出；或当天卖出, 当天要卖出，得前一天持有才行
			dp[1] = Math.max(dp[1], dp[0] + prices[i - 1]);
		}
		return dp[1];
	}
	public int maxProfit(int[] prices) {
		// 一次遍历 贪心
		// 先找出来最低点，也就是最小的数字
		//再找出来每一天你都想卖
		int maxValue=0;
		int minValue=Integer.MAX_VALUE;
		for(int i=0;i<prices.length;i++){
			if(prices[i]<minValue){
				minValue=prices[i];
			}else if(prices[i]-minValue>maxValue){
				maxValue=prices[i]-minValue;
			}
		}
		return maxValue;
	}
	//我们来假设自己来购买股票。随着时间的推移，每天我们都可以选择出售股票与否。那么，假设在第 i 天，如果我们要在今天卖股票，那么我们能赚多少钱呢？
	//
	//显然，如果我们真的在买卖股票，我们肯定会想：如果我是在历史最低点买的股票就好了！太好了，在题目中，我们只要用一个变量记录一个历史最低价格 minprice，我们就可以假设自己的股票是在那天买的。那么我们在第 i 天卖出股票能得到的利润就是 prices[i] - minprice。
	//
	//因此，我们只需要遍历价格数组一遍，记录历史最低点，然后在每一天考虑这么一个问题：如果我是在历史最低点买进的，那么我今天卖出能赚多少钱？当考虑完所有天数之时，我们就得到了最好的答案。
}
